import numpy as np
import matplotlib.pyplot as plt
from scipy import signal as scipy_signal
import json
import os

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False    # 用来正常显示负号

def load_filter_params():
    """加载滤波器参数"""
    current_file_path = os.path.abspath(__file__)
    current_dir = os.path.dirname(current_file_path)
    params_file = os.path.join(current_dir, "bandpass_filter_params.json")
    
    with open(params_file, 'r') as f:
        params = json.load(f)
    
    # 获取第一个频率范围的参数
    key = list(params.keys())[0]
    return params[key]['b'], params[key]['a']

def generate_sine_wave(freqs, amplitudes, fs, duration):
    """生成多个频率的正弦波叠加
    
    参数:
        freqs: 频率列表，单位为Hz
        amplitudes: 对应频率的幅度列表
        fs: 采样率，单位为Hz
        duration: 信号持续时间，单位为秒
    
    返回:
        t: 时间轴
        signal: 叠加后的信号
    """
    t = np.linspace(0, duration, int(fs * duration))
    signal = np.zeros_like(t)
    
    for freq, amp in zip(freqs, amplitudes):
        signal += amp * np.sin(2 * np.pi * freq * t)
    
    return t, signal

def apply_filter(signal_data, b, a):
    """应用滤波器"""
    return scipy_signal.filtfilt(b, a, signal_data)

def plot_signals(t, original, filtered):
    """绘制原始信号和滤波后的信号"""
    fig = plt.figure(figsize=(12, 6))
    
    # 绘制原始信号
    ax1 = plt.subplot(2, 1, 1)
    ax1.plot(t, original)
    ax1.set_title('原始信号', fontsize=12)
    ax1.set_xlabel('时间 (秒)', fontsize=10)
    ax1.set_ylabel('幅度', fontsize=10)
    ax1.grid(True)
    
    # 绘制滤波后的信号
    ax2 = plt.subplot(2, 1, 2)
    ax2.plot(t, filtered)
    ax2.set_title('滤波后的信号', fontsize=12)
    ax2.set_xlabel('时间 (秒)', fontsize=10)
    ax2.set_ylabel('幅度', fontsize=10)
    ax2.grid(True)
    
    plt.tight_layout()
    
    # 定义滚轮事件回调函数
    def on_scroll(event):
        if event.inaxes is None:
            return
        
        # 获取当前坐标轴
        ax = event.inaxes
        # 获取当前y轴范围
        y_min, y_max = ax.get_ylim()
        # 计算缩放范围
        scale = 0.1  # 缩放比例
        if event.button == 'up':
            # 放大
            y_min = y_min + (y_max - y_min) * scale
            y_max = y_max - (y_max - y_min) * scale
        elif event.button == 'down':
            # 缩小
            y_min = y_min - (y_max - y_min) * scale
            y_max = y_max + (y_max - y_min) * scale
        
        # 设置新的y轴范围
        ax.set_ylim(y_min, y_max)
        # 重绘图形
        fig.canvas.draw_idle()
    
    # 绑定滚轮事件
    fig.canvas.mpl_connect('scroll_event', on_scroll)
    
    plt.show()

def main():
    # 参数设置
    freqs = [5, 15, 25]  # 信号频率列表 (Hz)
    amplitudes = [1.0, 1.3, 1.5]  # 对应频率的幅度
    fs = 250  # 采样率 (Hz)
    duration = 10  # 信号持续时间 (秒)
    
    # 生成正弦波
    t, original_signal = generate_sine_wave(freqs, amplitudes, fs, duration)
    
    # 加载滤波器参数
    b, a = load_filter_params()
    
    # 应用滤波器
    filtered_signal = apply_filter(original_signal, b, a)
    
    # 绘制结果
    plot_signals(t, original_signal, filtered_signal)
    
    # 打印一些统计信息
    print(f"原始信号最大值: {np.max(original_signal):.3f}")
    print(f"滤波后信号最大值: {np.max(filtered_signal):.3f}")
    print(f"原始信号最小值: {np.min(original_signal):.3f}")
    print(f"滤波后信号最小值: {np.min(filtered_signal):.3f}")

if __name__ == "__main__":
    main()